﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Serialization;
using System.Text.RegularExpressions;
using System.ComponentModel;

namespace Nizm0.QOT.Library.Objects
{

    [Serializable]
    //[XmlInclude(typeof(Object))]
    [XmlRoot("ProcedureFromDatabase")]
    public class ProcedureFromDatabase : Procedure
    {

        [XmlAttribute("DataBase")]
        public string DataBase { get; set; }

        private string _location;
        [XmlAttribute("Location")]
        public override string Location
        {
            get
            {
                _location = string.Format("{0}.{1}.{2}.{3}", Server, DataBase, Owner, Name);
                return _location;
            }
            set { _location = value; }
        }

        [XmlAttribute("Owner")]
        public string Owner { get; set; }

        [XmlAttribute("Server")]
        public string Server { get; set; }

        //[XmlAttribute("text")]
        [XmlIgnore()]
        public override string Text
        {
            get
            {
                if (string.IsNullOrWhiteSpace(base.Text))
                {
                    return "";
                }
                return base.Text;
            }
            set
            {
                base.Text = value;
                if (!string.IsNullOrWhiteSpace(value))
                {

                    base._hash = GetMD5Hash(System.Security.Cryptography.MD5.Create(), value);

                    GetInfoOfProcedure();

                    GetParameters();
                }
            }
        }

        public ProcedureFromDatabase()
        {
        }

        public ProcedureFromDatabase(string procName, object parent)
            : base(procName)
        {
            Parent = (IProcedureInfo)parent;
            base.SourceType = Procedure.EnumSource.Database;
        }

        void bt1_Click(object sender, EventArgs e)
        {
            ReadDatabase();
        }

        public override T Deserialize<T>(string xmlobject)
        {
            byte[] byteArray = Encoding.Unicode.GetBytes(xmlobject);
            T ip;
            using (MemoryStream stream = new MemoryStream(byteArray))
            {
                System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(this.GetType());
                ip = (T)x.Deserialize(stream);
            }
            return ip;
        }

        public override void Marge(Procedure procedure)
        {
            this.DataBase = ((ProcedureFromDatabase)procedure).DataBase;
            this.Owner = ((ProcedureFromDatabase)procedure).Owner;
            this.Parent = ((ProcedureFromDatabase)procedure).Parent;
            this.Server = ((ProcedureFromDatabase)procedure).Server;
            this.Text = ((ProcedureFromDatabase)procedure).Text;
            base.Marge(procedure);
        }

        public bool ReadDatabase()
        {
            if (!LoadedFromSettings)
            {
                lock (this)
                {
                    if (!LoadedFromSettings)
                    {
                        //if (this.pattenrntab == null)
                        //    return false;
                        Objects.Server tmpserv;
                        Objects.DataBase tmpdatabase;
                        if (!string.IsNullOrWhiteSpace(this.Server) && !string.IsNullOrWhiteSpace(this.DataBase))
                        {
                            tmpserv = ProjectSettings.Instance.Servers.Find(s => s.Address == this.Server);
                            if (tmpserv == null)
                            {
                                tmpserv = new Objects.Server(this.Server);
                                tmpdatabase = new Objects.DataBase(this.DataBase);
                            }
                            else
                                tmpdatabase = tmpserv.DataBase.Find(d => d.Name == this.DataBase);
                        }
                        else
                        {
                            throw new ArgumentNullException(string.Format("Unnown Server or DataBase for object {0} : {1}", this.GetType().ToString(), this.Name), new Exception());
                        }

                        return Scripts.GetFromSQL.GetProcedure(tmpserv, tmpdatabase, this);

                        //base._hash = GetMD5Hash(System.Security.Cryptography.MD5.Create(), Text);

                        //GetInfoOfProcedure();

                        //GetParameters(); 
                        //((Server)((DataBase)proc.Parent).Parent)
                    }
                }
                return true;
            }
            else
                return false;
        }

        public override string Serialize()
        {
            //TextWriter w = new StringWriter();
            ////System.Runtime.Serialization.Formatters.Binary.BinaryFormatter t = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(
            //System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(typeof(ProcedureFromDatabase));
            //x.Serialize(w, this);
            //w.Flush();
            //return w.ToString();

            TextWriter w = new StringWriter();
            //System.Runtime.Serialization.Formatters.Binary.BinaryFormatter t = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(
            System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(typeof(ProcedureFromDatabase));
            x.Serialize(w, this, null);
            w.Flush();
            string text = w.ToString();
            return text;
        }

        public override System.Windows.Forms.UserControl Show()
        {
            System.Windows.Forms.Label tmplabel = new System.Windows.Forms.Label();
            tmplabel.Text = "Database " + this.Location;
            tmplabel.AutoSize = true;

            System.Windows.Forms.Button bt1 = new System.Windows.Forms.Button();
            bt1.Text = "Get";
            bt1.Click += new EventHandler(bt1_Click);

            System.Windows.Forms.Control[] tmpcontrolstab = { tmplabel, bt1 };

            return base.Show(tmpcontrolstab);
        }

        public override System.Windows.Forms.UserControl Show(IProcedure proc)
        {
            return base.Show(proc);
        }

        public override void ShowText()
        {
            base.ShowText();
        }

        public override string ToString()
        {
            return string.Format("{0}-{1} {2}", this.Name, this.Version, this.CreationTime.ToShortDateString());
        }

        public override System.Xml.Schema.XmlSchema GetSchema()
        {
            return base.GetSchema();
        }

        public override void ReadXml(System.Xml.XmlReader reader)
        {
            reader.MoveToContent();
            this._location = reader.GetAttribute("Location");
            this.DataBase = reader.GetAttribute("DataBase");
            this.Owner = reader.GetAttribute("Owner");
            this.Server = reader.GetAttribute("Server");
            base.ReadXml(reader);
        }

        public override void WriteXml(System.Xml.XmlWriter writer)
        {
            writer.WriteAttributeString("Location", this._location);
            writer.WriteAttributeString("DataBase", this.DataBase);
            writer.WriteAttributeString("Owner", this.Owner);
            writer.WriteAttributeString("Server", this.Server);
            base.WriteXml(writer);
        }
    }
}
